package com.jxltech.unicam;

import com.github.sarxos.webcam.Webcam;
import com.jxltech.unicam.utils.AudioPlayer;
import java.awt.*;
import java.io.IOException;
import java.io.InputStream;
import javax.imageio.ImageIO;
import javax.swing.JDialog;
import javax.swing.JOptionPane;
import javax.swing.JTextArea;

/**
 * Dialog displayed when switching panels/settings
 *
 * @author Jelmerro
 */
public class LoadingDialog extends JDialog {

    private JTextArea log;

    /**
     * Constructor of the dialog
     */
    public LoadingDialog() {
        //Call super method
        super(Frame.getInstance(), "加载中", ModalityType.APPLICATION_MODAL);
        //Set properties
        setResizable(false);
        setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
        Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
        setLocation(screen.width / 2 - 175, screen.height / 2 - 125);
        setSize(500, 400);
        //Add the log
        log = new PictureArea();
        log.setEditable(false);
        add(log);
    }

    /**
     * Shows the dialog and starts the process of switching panels/settings using the Task class
     *
     * @param res Dimension
     */
    public void load(Object leftWebcam, Object rightWebcam, Dimension res) {
        Task task = new Task(leftWebcam, rightWebcam, res);
        task.start();
        setVisible(true);
    }

    /**
     * Adds the specified string to the displayed log
     *
     * @param line String
     */
    private void addToLog(String line) {
        //Adds it to the textarea and prints it in the console
        log.setText(log.getText() + "\n" + line);
        System.out.println(line);
    }

    /**
     * Inner class Task, responsible for the steps needed to change panels/settings
     */
    private class Task extends Thread {

        Object leftWebcam;
        Object rightWebcam;
        Dimension res;

        /**
         * Constructor of a Task
         *
         * @param res Dimension
         */
        public Task(Object leftWebcam, Object rightWebcam,Dimension res) {
            this.leftWebcam = leftWebcam;
            this.rightWebcam = rightWebcam;
            this.res = res;
        }

        /**
         * Thread applying the new panels/settings
         */
        @Override
        public void run() {
            boolean error = false;
            //Stop the existing panel if needed
            if (Frame.getInstance().getLeftPanel() != null) {
                addToLog("停止当前显示");
                Frame.getInstance().getLeftPanel().stop();
                Frame.getInstance().getRightPanel().stop();
            }
            //Cast the provided object to a webcam
            //If it's null or not a webcam, this step will fail
            addToLog("设置摄像头");
            Webcam sLeftWebcam = null;
            Webcam sRightWebcam = null;
            try {
                sLeftWebcam = (Webcam) leftWebcam;
                sRightWebcam = (Webcam) rightWebcam;
            } catch (Exception ex) {
                addToLog(ex.toString());
                error = true;
            }
            //Continue only if the webcam is set
            if (sLeftWebcam != null) {
                //Try to set the requested resolution
                //This step shouldn't fail under regular circumstances
                addToLog("校准");
                try {
                    Dimension[] array = {res};
                    sLeftWebcam.setCustomViewSizes(array);
                    sRightWebcam.setCustomViewSizes(array);
                    sLeftWebcam.setViewSize(res);
                    sRightWebcam.setViewSize(res);
                } catch (Exception ex) {
                    addToLog(ex.toString());
                    error = true;
                }
                //Try to create the new panel
                //If another panel is using the webcam and is frozen, this step will fail
                addToLog("创建摄像面板");
                try {
                    ViewPanel leftPanel = new ViewPanel(sLeftWebcam);
                    ViewPanel rightPanel = new ViewPanel(sRightWebcam);
                    addToLog("创建面板");
                    leftPanel.setFPSDisplayed(true);
                    rightPanel.setFPSDisplayed(true);
                    Frame.getInstance().setPanel(leftPanel, rightPanel);
                    leftPanel.updateUI();
                    rightPanel.updateUI();
                } catch (Exception ex) {
                    addToLog(ex.toString());
                    error = true;
                }
                //If all went well, dispose the LoadingDialog and show a message if the resolution had to be changed
                //Else make the LoadingDialog wider, show the exception and allow closing of the dialog
                if (!error) {
                    addToLog("完成");
                    if (!res.equals(Frame.getInstance().getJpanelMain().getPreferredSize()) && !(res.getHeight() == 10000 && res.getWidth() == 10000)) {
                        Dimension panelSize = Frame.getInstance().getJpanelMain().getPreferredSize();
                        Frame.getInstance().getLeftPanel().drawMessage("Different resolution: " + (int) panelSize.getWidth() + "x" + (int) panelSize.getHeight() + " instead of " + (int) res.getWidth() + "x" + (int) res.getHeight());
                        Frame.getInstance().getRightPanel().drawMessage("Different resolution: " + (int) panelSize.getWidth() + "x" + (int) panelSize.getHeight() + " instead of " + (int) res.getWidth() + "x" + (int) res.getHeight());
                    }
                    dispose();
                } else {
                    setResizable(true);
                    Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
                    setLocation(screen.width / 2 - 250, screen.height / 2 - 100);
                    setSize(500, 200);
                    addToLog("您可以关闭窗口");
                    setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
                }
            } else {
                //Close the LoadingDialog if no webcam was found/selected
                dispose();
                addToLog("无可用摄像头");
                JOptionPane.showMessageDialog(null, "找不到可用摄像头", "摄像头", JOptionPane.WARNING_MESSAGE);
            }
        }
    }

    private class PictureArea extends JTextArea {
        private Image img;

        public PictureArea() {
            super();
            Image img = null;
            try {
                InputStream inStream = AudioPlayer.class.getClassLoader().getResourceAsStream("bg.jpg");
                img = ImageIO.read(inStream);
            } catch (IOException e) {
                e.printStackTrace();
            }
            this.img = img;
        }

        public Color getForeground() {
            return Color.RED;
        }

        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            if (img != null) {
                Graphics2D g2 = (Graphics2D) g.create();
                g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, .4f));
                g2.drawImage(img, 0, 0, getWidth(), getHeight(), this);
                g2.dispose();
            }
        }
    }

}
